<?php
	/**
	 * @package PHP_Logging
	 */
	/**
	 * @brief Abstract class for creating and accessing Log files
	 *
	 * - Revision History
	 *  - 0.1.1
	 * 	 - <b>Date</b>: 15 Jan 2011
	 * 	 - <b>Author</b>: Randy Blancett
	 * 	  - Added Loging of memory and time
	 *  - 0.1
	 * 	 - <b>Date</b>: 10 MAR 2010
	 * 	 - <b>Author</b>: Randy Blancett
	 * 	  - Initial Version
	 *
	 * @author Randy Blancett
	 * @version 0.1.1
	 * @ingroup AbstractClasses
	 */

	if (class_exists("abs_Log"))
	{
		return;
	}
	abstract class abs_Log
	{
		const c_str_ACTION_ERROR = "Error"; /**< Denotes that action being logged is an Error*/
		const c_str_ACTION_INFORMATION = "Information"; /**< Denotes that action being logged is Information*/
		const c_str_ACTION_VALUE = "Value"; /**< Denotes that action being logged is a Value*/
		const c_str_ACTION_MEMORY = "Memory"; /**< Denotes that action being logged is a Memory Benchmark*/
		const c_str_ACTION_TIME = "Time"; /**<Denotes that action being logged is a Time Benchmark*/

		const C_INT_LOG_FORMAT_FILE = 0; /**<Outputs Log as a file*/
		const C_INT_LOG_FORMAT_DATABASE = 1; /**<Outputs Log As database*/

		protected $m_str_Directory = null; /**< The base directory that the log files will be saved in*/
		protected $m_str_FileName = "Log"; /**< The Base Name of the Log File*/
		protected $m_int_LogLevel = 0; /**< The level of logging currently active*/
		protected $m_obj_FileHandler = null; /**< The object that handles file access*/
		protected $m_int_LogFormat = self::C_INT_LOG_FORMAT_FILE; /**< Determins what type of loging takes place*/

		protected $m_str_ConString = ""; /**< String used to connect to the database*/
		protected $m_str_DBUserName = ""; /**< Username used to connect to the database*/
		protected $m_str_DBPass = ""; /**< Password used to connect to the database*/

		private $m_bool_Active = false; /**< Sets if Logging is active*/
		private $m_bool_Benchmark = false; /**< Sets if benchmark is active*/

		private $m_obj_DBCon = null; /**< connection to database*/

		/**
		 * Holds time marks for Time benchmarks
		 */
		protected $m_arr_BenchmarkTime = array();

		/**
		 * Holds Memory marks for Memory benchmarks
		 */
		protected $m_arr_BenchmarkMemory = array();

		/**
		 * Called when class is destroyed
		 *  - Makes sure that the file handler is closed
		 *
		 */
		function __destruct()
		{
			if ($this->m_obj_FileHandler)
			{
				@fclose($this->m_obj_FileHandler);
			}
			if ($this->m_obj_DBCon)
			{
				unset($this->m_obj_DBCon);
			}
		}

		/**
		 * Activates Logging
		 */
		public function activate()
		{
			$this->m_bool_Active = true;
		}

		/**
		 * Activates Benchmarking;
		 */
		public function activate_Benchmark()
		{
			$this->m_bool_Benchmark = true;
		}

		/**
		 * Deactivates Benchmarking
		 */
		public function deactivate_Benchmark()
		{
			$this->m_bool_Benchmark = false;
		}

		/**
		 * Deactivates Logging
		 */
		public function deactivate()
		{
			$this->m_bool_Active = false;
		}

		/**
		 * This will set or reset a timer
		 * @param string $str_Name Name of the timer to use (default is "default")
		 */
		public function start_Timer($str_Name = null)
		{
			if (is_null($str_Name))
			{
				$str_Name = "default";
			}
			if ($this->m_bool_Benchmark)
			{
				$this->do_Log(self::c_str_ACTION_TIME, $str_Name . " - Startpoint Set");
			}
			$this->m_arr_BenchmarkTime["$str_Name"] = $this->get_MicroTime();
		}
		/**
		 * This will Output the elapsed time
		 * @param string $str_Name Name of the timer to use (default is "default")
		 */
		public function print_Time($str_Name = "default")
		{
			if ($this->m_bool_Benchmark)
			{
				$int_Time = $this->get_MicroTime() - $this->m_arr_BenchmarkTime[$str_Name];
				$this->do_Log(self::c_str_ACTION_TIME, $str_Name . " - Elapsed time - " . $int_Time);
			}
		}
		/**
		 * This will Output the Current memory used by this process
		 * @param string $str_Name Name of the Memory tracker to use (default is "default")
		 */
		public function print_Memory($str_Name = "default")
		{
			if ($this->m_bool_Benchmark)
			{
				$int_Memory = memory_get_usage(true) - $this->m_arr_BenchmarkMemory[$str_Name];
				$this->do_Log(self::c_str_ACTION_TIME, $str_Name . " - Used Memory - " . $int_Memory);
			}
		}

		/**
		 * This will set the current start point for the memory usage
		 * @param string $str_Name Name of the Memory tracker to use (default is "default")
		 */
		public function start_Memory($str_Name = "default")
		{
			if ($this->m_bool_Benchmark)
			{
				$this->do_Log(self::c_str_ACTION_MEMORY, $str_Name . " - Startpoint Set");
			}
			$this->m_arr_BenchmarkMemory[$str_Name] = memory_get_usage(true);
		}

		private function get_DBCon()
		{
			if (!isset($this->m_obj_DBCon))
			{
				try
				{
					$this->m_obj_DBCon = new PDO($this->m_str_ConString, $this->m_str_DBUserName, $this->m_str_DBPass);
				}
				catch (PDOException $e)
				{
					Print $e->getMessage();
					return null;
				}
			}

			return $this->m_obj_DBCon;
		}

		/**
		 * Gets the micro time as a float
		 * @return float current microtime
		 */
		protected function get_MicroTime()
		{
			$obj_Time = microtime();
			$obj_Time = explode(" ", $obj_Time);
			$obj_Time = $obj_Time[1] + $obj_Time[0];
			return $obj_Time;
		}

		/**
		 * Changes base name of the Log file
		 * @param string $str_FileName New file name for log file
		 */
		public function set_FileName($str_FileName)
		{
			$this->m_str_FileName = $str_FileName;
			if ($this->m_obj_FileHandler)
			{
				@fclose($this->m_obj_FileHandler);
			}
			$this->m_obj_FileHandler = null;
			return true;
		}

		/**
		 * Sets the base Directory where Log files are stored
		 * @param string $str_Directory Directory where log files should be stored
		 * @param boolean $bool_CreateDirectory If true the directory will be created
		 * @return boolean True if Directory was changed False if there was an error
		 */
		public function set_Directory($str_Directory, $bool_CreateDirectory = false)
		{
			if (!file_exists($str_Directory))
			{
				if ($bool_CreateDirectory)
				{
					if (!mkdir($str_Directory, "0777", true))
					{
						$this->m_str_Directory = null;
						return false;
					}
				}
			}
			$this->m_str_Directory = $str_Directory;
			if ($this->m_obj_FileHandler)
			{
				@fclose($this->m_obj_FileHandler);
			}
			$this->m_obj_FileHandler = null;
			return true;
		}

		/**
		 * Sets the level of active logging
		 * @param $int_LogFormat $int_LogLevel Log format
		 */
		public function set_LogFormat($int_LogFormat)
		{
			$this->m_int_LogFormat = $int_LogFormat;
		}

		/**
		 * Sets the Connection String used to connect to the Database
		 * @param string $str_Con The new logging level
		 */
		public function set_ConStr($str_Con)
		{
			$this->m_str_ConString = $str_Con;
		}

		/**
		 * Sets the Database User Name
		 * @param string $str_User The User Name
		 */
		public function set_DBUserName($str_User)
		{
			$this->m_str_DBUserName = $str_User;
		}
		/**
		 * Sets the Database Password
		 * @param string $str_Password The User Name
		 */
		public function set_DBPassword($str_Password)
		{
			$this->m_str_DBPass = $str_Password;
		}

		/**
		 * Sets the Format of the Log output
		 * @param integer $int_LogLevel The new logging level
		 */
		public function set_LogLevel($int_LogLevel)
		{
			$this->m_int_LogLevel = $int_LogLevel;
		}

		/**
		 * Opens / Creates the Log file
		 * @return boolean True if file was successfuly opened false if it failed
		 */
		protected function open_File()
		{
			if (!$this->m_obj_FileHandler)
			{
				$str_FileName = $this->m_str_Directory . "/" . $this->m_str_FileName . ".LOG";

				if (!$this->create_Dir($this->m_str_Directory))
				{
					print("Failed to create directory\n");
					return false;
				}

				if (file_exists($str_FileName))
				{
					$this->m_obj_FileHandler = fopen($str_FileName, "a");
				}
				else
				{
					//$int_OldMask = umask(0);

					$this->m_obj_FileHandler = fopen($str_FileName, "w");
					if ($this->m_obj_FileHandler)
					{
						fwrite($this->m_obj_FileHandler, date("F d, Y H:i:s") . " - Log Created \n");
					}
					//chmod($str_FileName,0777);
					//umask($int_OldMask);
				}
				if (!$this->m_obj_FileHandler)
				{
					return false;
				}
			}
			return true;
		}
		/**
		 * Creates a directory if it does not already exist
		 * @param string $str_DirPath Path to be created
		 * @return boolean true - Directory Exists false - directory does not exist and can not be created.
		 */
		protected function create_Dir($str_DirPath)
		{
			$bool_Return = false;
			if (file_exists($str_DirPath))
			{
				return true;
			}

			$int_OldMask = umask(0);
			if (@mkdir($str_DirPath, 0777, true))
			{
				$bool_Return = true;
			}
			else
			{
				$bool_Return = false;
			}
			umask($int_OldMask);

			return $bool_Return;
		}

		/**
		 *
		 * @param string $str_LogType Type of Action being loged
		 * @param string $str_LogData Text to be writen to log
		 * @param integer $int_LogLevel Level of the event if Greater than the active Log level it will not be logged
		 * @return integer
		 * <ul>
		 * 		<li>
		 * 			-2 - could not connect to database
		 * 		</li>
		 * 		<li>
		 * 			-1 - Log file failed to open
		 * 		</li>
		 * 		<li>
		 * 			0 - Success
		 * 		</li>
		 * 		<li>
		 * 			1 - Logging is not Active
		 * 		</li>
		 * 		<li>
		 * 			2 - Event Level is not Tracked in the current Logging Level
		 * 		</li>
		 * </ul>
		 */
		public function do_Log($str_LogType, $str_LogData, $int_LogLevel = 0)
		{
			if (!$this->m_bool_Active)
			{
				return 1;
			}

			if ($int_LogLevel > $this->m_int_LogLevel)
			{
				return 2;
			}

			switch ($this->m_int_LogFormat)
			{
				case self::C_INT_LOG_FORMAT_FILE:
					$this->do_FileLog($str_LogType, $str_LogData);
					break;
				case self::C_INT_LOG_FORMAT_DATABASE:
					$this->do_DBLog($str_LogType, $str_LogData);
					break;
				default:
					print("Unknown Log Format");
			}

		}
		/**
		 * Outputs Log information to a file
		 * @param string $str_LogType Type of Action being loged
		 * @param string $str_LogData Text to be writen to log
		 * @return integer
		 * <ul>
		 * 		<li>
		 * 			-1 - Log file failed to open
		 * 		</li>
		 * 		<li>
		 * 			0 - Success
		 * 		</li>
		 * </ul>
		 */
		protected function do_FileLog($str_LogType, $str_LogData)
		{
			if ($this->open_File())
			{
				fwrite($this->m_obj_FileHandler, date("F d, Y H:i:s") . " - " .
					$str_LogType . " - " . $str_LogData . " \n");
			}
			else
			{
				return -1;
			}
			return 0;
		}

		/**
		 * Outputs Log information to a file
		 * @param string $str_LogType Type of Action being loged
		 * @param string $str_LogData Text to be writen to log
		 * @return integer
		 * <ul>
		 * 		<li>
		 * 			-2 - could not connect to database
		 * 		</li>
		 * 		<li>
		 * 			0 - Success
		 * 		</li>
		 * </ul>
		 */
		protected function do_DBLog($str_LogType, $str_LogData)
		{
			$obj_Con = $this->get_DBCon();
			if (!isset($obj_Con))
			{
				return -2;
			}

			print("Connected To DB");
			return 0;
		}
	}
?>